home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / yk211src.lha / Yak_2.11_Src / WBStartup / main.c < prev    next >
C/C++ Source or Header  |  1995-10-18  |  14KB  |  526 lines

  1. /*
  2.  * Yak version 2.00
  3.  * ----------------
  4.  * [Yak == Yet Another K(?)ommodity
  5.  *
  6.  * There seems to be a profusion of commodities doing this or that.
  7.  * Heres mine, to do what I want it to:
  8.  *
  9.  *      AutoActivate windows (SunMouse)
  10.  *      ClickToFront, ClickToBack, ScreenCycle
  11.  *      Close/Zip/Shrink/Zoom/Turn a window via keyboard.
  12.  *      Bring up a palette on front screen.
  13.  *      Insert date into read-stream.
  14.  *      Produce key-click (like my keyclick program).
  15.  *      Some other things...
  16.  *
  17.  * Martin W. Scott, Gaël Marziou & Philippe Bastiani, 7/94.
  18.  */
  19.  
  20. #define __USE_SYSBASE 
  21.  
  22. #include <exec/types.h>
  23. #include <exec/libraries.h>
  24. #include <exec/memory.h>
  25. #include <devices/inputevent.h>
  26. #include <dos/dos.h>
  27. #include <dos/dostags.h>
  28. #include <dos/notify.h>
  29. #include <graphics/displayinfo.h>
  30. #include <libraries/commodities.h>
  31. #include <libraries/reqtools.h>
  32. #include <libraries/locale.h>
  33. #include <intuition/intuitionbase.h>
  34. #include <workbench/startup.h>
  35. #include <clib/alib_protos.h>
  36.  
  37. #include <proto/exec.h>
  38. #include <proto/dos.h>
  39. #include <proto/graphics.h>
  40. #include <proto/commodities.h>
  41. #include <proto/icon.h>
  42. #include <proto/iffparse.h>
  43. #include <proto/intuition.h>
  44. #include <proto/layers.h>
  45. #include <proto/locale.h>
  46. #include <proto/reqtools.h>
  47. #include <proto/wb.h>
  48.  
  49. #include <string.h>
  50.  
  51. #include "Code.h"
  52. #include "yak.h"
  53. #include "hotkey_types.h"
  54. #include "beep.h"
  55. #include "Handlers.h"
  56. #include "icon.h"
  57. #include "version.h"
  58. #include "Requesters.h"
  59. #include "Settings.h"
  60. #include "Pri.h"
  61. #include "UnixDirs.h"
  62. #include "LastActiveWindow.h"
  63.  
  64. #define CATCOMP_BLOCK
  65. #define CATCOMP_NUMBERS
  66. #include "yak_locale_strings.h"
  67. #undef CATCOMP_BLOCK
  68.  
  69. #ifdef USE_WB2CLI
  70. #  include "WB2CLI.h"     /* we'll be a shell process */
  71. #endif
  72.  
  73. #define DEF_CURRENTDIR  "SYS:"
  74.  
  75. /* local prototypes for main.c */
  76. static void CloseResources(void);
  77. static BOOL OpenResources(void);
  78. static void FreePatterns(void);
  79. static LONG ProcessMsg(void);
  80. void MAIN(void);
  81.  
  82.  
  83. extern struct WBStartup *WBMsg;
  84. /*
  85.  *  libraries opened by startup code; basepointers needed by function pragmas
  86.  */
  87.  
  88. #if defined(_DCC)
  89.  
  90. extern struct ExecBase       *SysBase;
  91. extern struct DosLibrary     *DOSBase;
  92.  
  93. struct IntuitionBase  *IntuitionBase;
  94. struct GfxBase        *GfxBase;
  95.  
  96. /* global data - library bases and the like */
  97. struct Library  *CxBase, *IconBase,
  98.                 *LayersBase,
  99.                 *WorkbenchBase,
  100.                 *IFFParseBase;
  101.  
  102. #endif
  103.  
  104. struct MsgPort *broker_mp;
  105. CxObj *broker;
  106. char *PopKeyStr;
  107. #define POPKEY_EVENT    1L      /* cannot clash with YHK event... */
  108.  
  109. char *PrefsPrg;
  110.  
  111.  
  112. struct NewBroker newbroker = {
  113.     NB_VERSION,
  114.     "Yak",                                              /* string to identify this broker */
  115.     VERSION_BROKER,
  116.     "Multi-purpose commodity",
  117.     NBU_UNIQUE | NBU_NOTIFY,    /* Don't want any new commodities
  118.                                  * starting with this name.  If someone
  119.                                  * tries it, let me know */
  120.     COF_SHOW_HIDE
  121. };
  122.  
  123. ULONG           cxsigflag;
  124. ULONG           invariantsigflag;
  125. BYTE            palette_count;          /* how many palettes are open */
  126.  
  127.  
  128. /* from icon.c */
  129. extern ULONG    appsigflag;
  130.  
  131.  
  132. /* close what we opened */
  133. static void
  134. CloseResources()
  135. {
  136.         /* NULL pointers are valid so don't waste time to test them */
  137.         CloseLibrary((struct Library *)IntuitionBase);
  138.         CloseLibrary((struct Library *)GfxBase);
  139.         CloseLibrary(CxBase);
  140.         CloseLibrary(LayersBase);
  141.         CloseLibrary(IconBase);
  142.         CloseLibrary(WorkbenchBase);
  143.         CloseLibrary(IFFParseBase);
  144.         CloseLocaleStuff();
  145. }
  146.  
  147.  
  148.  
  149. /* open libraries, devices that we need */
  150. static BOOL
  151. OpenResources(void)
  152. {
  153.         if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37L)) &&
  154.                 (GfxBase       = (struct GfxBase *)OpenLibrary("graphics.library", 37L)) &&
  155.                 (CxBase        = OpenLibrary("commodities.library", 37L)) &&
  156.                 (LayersBase    = OpenLibrary("layers.library", 37L)) &&
  157.                 (IconBase      = OpenLibrary("icon.library", 37L)) &&
  158.                 (WorkbenchBase = OpenLibrary("workbench.library", 37L)) &&
  159.                 (IFFParseBase  = OpenLibrary("iffparse.library", 37L)))
  160.         {
  161.                 return TRUE;
  162.         }
  163.         CloseResources();
  164.         return FALSE;
  165. }
  166.  
  167.  
  168.  
  169. static void
  170. FreePatterns()
  171. {
  172.         UWORD i;
  173.  
  174.         for (i = 0; i < NUM_PATTERNS; i++)
  175.                 if (patterns[i].pat) FreeVec(patterns[i].pat);
  176. }
  177.  
  178.  
  179. BOOL
  180. ShowYakInterface(void)
  181. {   
  182.    BPTR infh;
  183.    BPTR ppl;
  184.  
  185.    if (ppl=Lock(PrefsPrg, ACCESS_READ))
  186.    {
  187.        UnLock(ppl);
  188.    
  189.        if (infh=Open("Nil:", MODE_OLDFILE))
  190.        {
  191.            SystemTags(PrefsPrg, SYS_Input,  infh,
  192.                                 SYS_Output, NULL,
  193.                                 SYS_Asynch, TRUE,
  194.                                 TAG_DONE);
  195.        }
  196.  
  197.        return TRUE;
  198.    }
  199.  
  200.    PostError("%s\n\"%s\"", getString(Launching_prefs_program_ERR), PrefsPrg);
  201.    return(FALSE);
  202. }
  203.  
  204.  
  205. static LONG notifysigbit;
  206. static ULONG notifysigflag;
  207. static struct NotifyRequest NotifyRequest;
  208.  
  209.  
  210. void
  211. EndNotification(void)
  212. {
  213.    EndNotify(&NotifyRequest);
  214.    FreeSignal(notifysigbit);
  215. }
  216.  
  217. void
  218. SetNotification(void)
  219. {
  220.         /* Allocate a signalsbit */
  221.         if ((notifysigbit = AllocSignal(-1L)) != -1)
  222.         {
  223.                 notifysigflag = 1 << notifysigbit;
  224.  
  225.                 /* Initialize notification request */
  226.  
  227.                 NotifyRequest.nr_Name = ENV_CONFIG_FILE;
  228.                 NotifyRequest.nr_Flags = NRF_SEND_SIGNAL; 
  229.                 /* Signal this task */
  230.                 NotifyRequest.nr_stuff.nr_Signal.nr_Task = (struct Task *) FindTask(NULL);
  231.                 /* with this signals bit */
  232.                 NotifyRequest.nr_stuff.nr_Signal.nr_SignalNum = notifysigbit;
  233.  
  234.                 StartNotify(&NotifyRequest);
  235.         }
  236. }
  237.  
  238.  
  239.  
  240. #ifdef _DCC
  241. void _waitwbmsg(void);
  242. static void
  243. uncalled(void)
  244. {
  245.     _waitwbmsg();
  246. }
  247. #endif
  248.  
  249. UBYTE FRONT_DELAY, BACK_DELAY;
  250.  
  251.  
  252. void MAIN()             /* Yak: multi-function commodity */
  253. {
  254.     BPTR newdir=NULL, olddir;
  255.     STRPTR ProgramName;
  256.  
  257.     if (OpenResources())
  258.     {
  259.         if (broker_mp = CreateMsgPort())
  260.         {
  261.             newbroker.nb_Port = broker_mp;
  262.             cxsigflag = 1L << broker_mp->mp_SigBit;
  263.  
  264.             if (WBMsg)          /* WB Startup */
  265.             {
  266.                 struct WBArg *wbarg=&WBMsg->sm_ArgList[0];
  267.  
  268.                 /* Get Program Name */
  269.                 if (ProgramName=AllocVec(256, MEMF_CLEAR))
  270.                 {
  271.                     BPTR lock=GetProgramDir();
  272.                     if (NameFromLock(lock, ProgramName, 256))
  273.                         AddPart(ProgramName, wbarg->wa_Name, 256);
  274.                 }
  275.  
  276.                 /* Current Directory */
  277.                 if (newdir = Lock(DEF_CURRENTDIR, ACCESS_READ))
  278.                     olddir = CurrentDir(newdir);
  279. #ifdef USE_WB2CLI
  280.                 WB2CLI(WBMsg,4000,(struct DosLibrary *)DOSBase); /* get it over with... */
  281. #endif
  282.             }                        
  283.             else                /* CLI Startup */
  284.             {
  285.                 /* Get Program Name */
  286.                 if (ProgramName=AllocVec(256, MEMF_CLEAR))
  287.                     GetProgramName(ProgramName, 256);
  288.             }
  289.  
  290.             /* process tool-types */
  291.             GetOurIcon(ProgramName);
  292.  
  293.             newbroker.nb_Pri = (BYTE)TTInt("CX_PRIORITY", 0);
  294.  
  295.             FRONT_DELAY=(UBYTE)TTInt("FRONT_DELAY", 6);
  296.             BACK_DELAY=(UBYTE)TTInt("BACK_DELAY", 6);
  297.  
  298.             if (broker = CxBroker(&newbroker, NULL))
  299.             {
  300.                 /* HANDLER FIRST, SO IT SEES EVERYTHING!!! */
  301.                 if (InitMainHandler())
  302.                 {
  303.                     InitYakHotKeyList();
  304.  
  305.                     /* Open the right locale if tooltype LANGUAGE is used */
  306.                     OpenLocaleStuff(TTString("LANGUAGE",NULL));
  307.  
  308.                     PrefsPrg = DupStr(TTString("PREFSPRG", "Sys:Prefs/Yak"));
  309.  
  310.                     if (PopKeyStr = DupStr(TTString("CX_POPKEY", "Rcommand help")))
  311.                     {
  312.                         CxObj *tmpobj;
  313.  
  314.                         if (tmpobj = HotKey(PopKeyStr, broker_mp, POPKEY_EVENT))
  315.                             AttachCxObj(broker, tmpobj);
  316.                         else
  317.                             PostError("%s:\"%s\"", getString(CX_POPKEY_invalid_ERR),
  318.                                       PopKeyStr);
  319.                     }
  320.                     /* else... if this failed, we lose */
  321.  
  322.                     MyPri(ACTIVE);
  323.  
  324.                     LoadSettings(ENV_CONFIG_FILE);
  325.  
  326.                     ActivateCxObj(broker, 1L);
  327.  
  328.                     if (TTBool("CX_POPUP", FALSE))
  329.                         ShowYakInterface();
  330.  
  331.                     if (TTBool("APPICON", FALSE))
  332.                     {
  333.                         if (!MakeOurAppIcon(TTString("ICONNAME", "Yak!")))
  334.                             if (WBMsg)
  335.                                 PostError(getString(Couldn_t_create_AppIcon_ERR));
  336.                     }
  337.                     /* WB makes a copy of icon, so can free it */
  338.                     FreeOurIcon();
  339.  
  340.                     /*
  341.                      * We want to be notified each time either
  342.                      * ENV:yak.prefs is modified (by Yak Preferences)
  343.                      */
  344.                     SetNotification();
  345.  
  346.                     /* these are the signals waited for, + window sig */
  347.                     invariantsigflag = SIGBREAKF_CTRL_C | cxsigflag
  348.                         | clicksigflag | intuiopsigflag | blankscreensigflag
  349.                             | appsigflag | notifysigflag | depthscreensigflag;
  350.  
  351.                     while (ProcessMsg())
  352.                         ;
  353.                     RemoveOurAppIcon();
  354.                     DeleteYakHotKeyList();
  355.  
  356.                     FreeVec(PopKeyStr);
  357.                     FreeVec(PrefsPrg);
  358.                     MyPri(ORIGINAL);
  359.  
  360.                     EndNotification();
  361.                     EndMainHandler();
  362.                     FreePatterns();
  363.                     CleanMouseCycling();
  364.                 }
  365.                 else
  366.                     PostError(getString(Allocation_ERR));
  367.         
  368.                 DeleteCxObjAll(broker);
  369.             }
  370.  
  371.             if (newdir)
  372.             {
  373.                 CurrentDir(olddir);
  374.                 UnLock(newdir);
  375.             }
  376.             DeleteMsgPort(broker_mp);
  377.  
  378.             FreeOurIcon();      /* may already be gone, but so what? */
  379.  
  380.             if (ProgramName) FreeVec(ProgramName);
  381.         }
  382.         else PostError(getString(Allocation_ERR));
  383.  
  384.                 ToggleUnixDirs( FALSE );
  385.  
  386.         CloseResources();
  387.     }
  388.     else PostError(getString(Resource_ERR));
  389. }
  390.  
  391. IMPORT BYTE oldpri; /* priority before handlers.c changed it */
  392.  
  393. ULONG secs, micros;
  394.  
  395. /* monitor cx port, act on messages */
  396. static LONG
  397. ProcessMsg(void)
  398. {
  399.     CxMsg *msg;
  400.     ULONG sigrcvd, msgid, msgtype;
  401.         struct InputEvent *ie;
  402.     LONG returnvalue = 1L;
  403.  
  404.     sigrcvd = Wait(invariantsigflag);
  405.  
  406.     if (sigrcvd & intuiopsigflag) 
  407.     {
  408.         /* intuiop requested */
  409.         intui_routine(intui_parameter); 
  410.  
  411.     }
  412.  
  413.     if ((sigrcvd & clicksigflag) && click_volume) /* keyclick please */
  414.     {
  415.         beep(click_volume);
  416.     }
  417.  
  418.     if (sigrcvd & depthscreensigflag) /* screen depth gadget has been pressed */
  419.     {
  420.         ScreenDepthGadget();
  421.     }
  422.     
  423.     if (sigrcvd & blankscreensigflag) /* blank screen please */
  424.     {
  425.         BlankScreen();
  426.     }
  427.     
  428.     if (sigrcvd & appsigflag)   /* start the prefs program */
  429.     {
  430.         ClearAppMsgPort();
  431.         ShowYakInterface();
  432.     }
  433.  
  434.     if (sigrcvd & notifysigflag) /* settings have changed */
  435.     {
  436.         LoadSettings(ENV_CONFIG_FILE);
  437.     }
  438.  
  439.     while(msg = (CxMsg *)GetMsg(broker_mp))
  440.     {
  441.         msgid = CxMsgID(msg);
  442.         msgtype = CxMsgType(msg);
  443.         if(msgtype==CXM_IEVENT) 
  444.         {
  445.                 /*
  446.                  *  copy the interesting data of the inputevent
  447.                  */
  448.                 ie = (struct InputEvent *)CxMsgData(msg);
  449.                 secs = ie->ie_TimeStamp.tv_secs;
  450.                 micros = ie->ie_TimeStamp.tv_micro;
  451.         }
  452.         ReplyMsg((struct Message *)msg);
  453.  
  454.         switch(msgtype)
  455.         {
  456.           case CXM_IEVENT:
  457.             switch (msgid)
  458.             {
  459.                     /* The msgid is used in 2 different ways:
  460.                      * as a simple event number for both POPKEY_EVENT and mouse cycling events
  461.                      * as a pointer to the structure of the hotkey to process
  462.                      *
  463.                      * This may look like a kludge but we can use safely small numbers for events
  464.                      * because they will be out of adresses range. Low addresses are located in ROM.
  465.                      */
  466.  
  467.               case POPKEY_EVENT:
  468.                     ShowYakInterface();
  469.                     break;
  470.  
  471.               case WINDOW_TOFRONT_EVENT:
  472.               case WINDOW_TOBACK_EVENT:
  473.               case SCREENCYCLING_EVENT:
  474.                     /* Execute function attached to this event */
  475.                     (*(MouseCyclingHandlers[msgid-WINDOW_TOFRONT_EVENT].HandlerFunction))();
  476.                     break;
  477.  
  478.               default:
  479.                     /* a generic hotkey... */
  480.                     PerformAction((YakHotKey *)msgid);
  481.                     break;
  482.  
  483.             }
  484.             break;
  485.  
  486.           case CXM_COMMAND:
  487.             switch(msgid)
  488.             {
  489.               case CXCMD_UNIQUE:
  490.               case CXCMD_APPEAR:
  491.                 ShowYakInterface();
  492.                break;
  493.  
  494.               case CXCMD_DISAPPEAR:
  495.                 BrokerCommand("Yak_Prefs", CXCMD_DISAPPEAR);
  496.                 break;
  497.  
  498.               case CXCMD_DISABLE:
  499.                 ActivateCxObj(broker, 0L);
  500.                 TurnMouseOn();
  501.                 break;
  502.  
  503.               case CXCMD_ENABLE:
  504.                 ActivateCxObj(broker, 1L);
  505.                 break;
  506.  
  507.               case CXCMD_KILL:
  508.                 returnvalue = 0L;
  509.                 break;
  510.             }
  511.             break;
  512.         }
  513.     }
  514.  
  515.     if (sigrcvd & SIGBREAKF_CTRL_C)
  516.         returnvalue = 0L;
  517.  
  518.     if (!returnvalue && !OkayToExit())
  519.     {
  520.         PostError(getString(Cannot_exit_palette_opened_ERR));
  521.         returnvalue = 1;
  522.     }
  523.     
  524.     return(returnvalue);
  525. }
  526.